from django.views import View
from elasticsearch import Elasticsearch
from django.http import HttpResponse
import requests
import json
# 天气：https://free-api.heweather.com/v5/weather?city=闵行&key=5f5cbc0222bf49709c1c7f14d7016702
SECRET = '5f5cbc0222bf49709c1c7f14d7016702'
WEATHER_URL = 'https://free-api.heweather.com/v5/weather?city={}&key=' + SECRET
REQUEST_FAILED = u'requesting api failed'
UNKNOWN_CITY = u'unknown city'
AMBIGUOUS_CITY = u'ambiguous city'
CONNECTION_ERROR = 'connection error'
# WEATHER_RESULT_FORMAT = u'{}: 最高温度: {}, 最低温度: {}'


class MovieSearchView(View):
    index_name = 'entertainment'
    type_name = 'qq_movie'
    es = None

    def dispatch(self, request, *args, **kwargs):
        try:
            self.es = Elasticsearch(http_auth=(
                'elastic', 'elastic'), timeout=2)
        except Exception as e:
            data = json.dumps(
                {"movie": {"status": CONNECTION_ERROR}}, ensure_ascii=False)

            return HttpResponse(data)
        else:
            return super(MovieSearchView, self).dispatch(
                request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        data = {}
        if 'movie' in request.GET and 'id' not in request.GET:
            movie = request.GET['movie']
            result = self.dosearch_movie(movie)
            data['movie'] = result
        elif 'id' in request.GET and 'movie' not in request.GET:
            id = request.GET['id']
            result = self.dosearch_id(id)
            data['movie'] = result
        elif 'movie' in request.GET and 'id' in request.GET:
            movie = request.GET['movie']
            id = request.GET['id']
            result = self.dosearch_movie_id(movie, id)
            data['movie'] = result
        else:
            data['movie'] = {"status": "invalid key"}
        return HttpResponse(json.dumps(data, ensure_ascii=False))

    def dosearch_movie(self, q):
        search_body = {
            "query": {
                "match": {
                    "label": {
                        "query": q,
                        "analyzer": "ik_smart",
                        "operator": "and"
                    }
                }
            }
        }
        try:
            result = self.es.search(index=self.index_name,
                                    doc_type=self.type_name,
                                    body=search_body, request_timeout=5)
        except Exception:
            return {'status': CONNECTION_ERROR}
        else:
            return_result = []
            for hit in result['hits']['hits']:
                return_result.append(hit['_source'])
            return return_result

    def dosearch_id(self, q):
        search_body = {
            "query": {
                "term": {
                    "id": {
                        "value": q
                    }
                }
            }
        }
        try:
            result = self.es.search(index=self.index_name,
                                    doc_type=self.type_name,
                                    body=search_body, request_timeout=5)
        except Exception as e:
            return {'status': CONNECTION_ERROR}
        else:
            return_result = []
            for hit in result['hits']['hits']:
                return_result.append(hit['_source'])
            return return_result

    def dosearch_movie_id(self, movie, id):
        search_body = {
            "query": {
                "bool": {
                    "must": [
                        {
                            "term": {
                                "id": {
                                    "value": id
                                }
                            }
                        },
                        {
                            "match": {
                                "label": {
                                    "query": movie,
                                    "analyzer": "ik_smart",
                                    "operator": "and"
                                }
                            }
                        }
                    ]
                }
            }
        }
        try:
            result = self.es.search(index=self.index_name,
                                    doc_type=self.type_name,
                                    body=search_body, request_timeout=5)
        except Exception as e:
            return {'status': CONNECTION_ERROR}
        else:
            return_result = []
            for hit in result['hits']['hits']:
                return_result.append(hit['_source'])
            return return_result


class WeatherSearchView(View):
    def get(self, request, *args, **kwargs):
        data = {}
        if 'city' in request.GET:
            city = request.GET['city']
            try:
                r = requests.get(WEATHER_URL.format(city), timeout=1)
            except Exception as e:
                data = json.dumps({"movie":
                                   {"status": CONNECTION_ERROR}},
                                  ensure_ascii=False)
                return HttpResponse(data)
            if r.status_code == requests.codes.ok:
                data['weather'] = self.parse_weather(r.text)
            else:
                data['weather'] = {"status": REQUEST_FAILED}
        else:
            data['weather'] = {"status": "invalid key"}
        return HttpResponse(json.dumps(data, ensure_ascii=False))

    def parse_weather(self, json_str):
        if UNKNOWN_CITY in json_str:
            return {'status': UNKNOWN_CITY}
        json_obj = json.loads(json_str)
        if len(json_obj['HeWeather5']) != 1:
            return {'status': AMBIGUOUS_CITY}
        return_dic = {}
        return_dic['status'] = json_obj['HeWeather5']
        return return_dic
